/*
 * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package com.net.MinaEngine.service;


import com.alibaba.fastjson.JSON;
import org.apache.mina.core.buffer.IoBuffer;

import javax.annotation.PostConstruct;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;


/**
 * User: 石头哥哥
 * Date: 13-5-26
 * Time: 上午9:59
 * Connect: 13638363871@163.com
 */
public abstract class HandleController implements IController {

    public static final CharsetDecoder decoder = (Charset.forName("UTF-8"))
            .newDecoder();


    /**
     *通过spring的方式初始化处理业务逻辑的javabean；
     *但是在实际中可能采取其他方式，如果不依赖于spring的条件下
     */
    @PostConstruct
    public abstract void PostConstruct();

    /**
     * 释放buffer
     * @param buffer
     */
    @Override
    public void releaseBuf(IoBuffer buffer){
        buffer.free();
    }

    /**
     * @return
     */
    @Override
    public IoBuffer creatIoBuffer() {
        return IoBuffer.allocate(0x40).setAutoExpand(true);
    }

    /**
     * @param capacity
     * @return
     */
    @Override
    public IoBuffer creatIoBuffer(int capacity) {
        return IoBuffer.allocate(capacity).setAutoExpand(true);
    }
    /**
     * 解析buffer数据为json对象
     * @param buffer
     * @param clazz    java bean class
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public Object parseObject(IoBuffer buffer, Class clazz) throws CharacterCodingException {
        Object o= JSON.parseObject(buffer.getString(decoder), clazz);
        releaseBuf(buffer);
        return o;
    }

    /**
     * 解析buffer数据为json对象
     * @param buffer
     * @param clazz    java bean class
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public Object parseObject(byte[] buffer, Class clazz) throws CharacterCodingException {
        Object o= JSON.parseObject(buffer, clazz);
        return o;
    }
    /**
     * read a byte (1 code)
     *
     * @param buffer buffer
     * @return byte
     */
    @Override
    public byte readByte(IoBuffer buffer) {
        return buffer.get();
    }

    /**
     * read a short (2 code)
     *
     * @param buffer buffer
     * @return short
     */
    @Override
    public short readShort(IoBuffer buffer) {
        return buffer.getShort();
    }

    /**
     * read a short (4 code)
     *
     * @param buffer buffer
     * @return int
     */
    @Override
    public int readInt(IoBuffer buffer) {
        return buffer.getInt();
    }
    /**
     * @param buffer 待处理数据缓存区
     * @return message
     *         如果默认读取1字节(readBytes())长度的字符串，那么该方法传入buffer将直接返回相应的字符串
     *         编码格式:utf-8
     */
    @Override
    public String readStringUTF8(IoBuffer buffer) throws CharacterCodingException {
        int length=buffer.get();
        return buffer.getString(length,decoder);
    }
    /**
     * @param buffer 待处理数据缓存区
     * @param length 读取指定的数据长度  readBytes() ,readShort() or readLong();
     * @return message
     *         编码格式:utf-8
     */
    @Override
    public String readStringUTF8(IoBuffer buffer, int length) throws CharacterCodingException {
        return buffer.getString(length,decoder);
    }

    /**
     * 构建数据包 ，处理一级类型数据包
     * 注意：此方法适应的协议是：
     * paras数据结构-----> length+msg+length+msg ... ...
     * length: byte(1字节),short（2字节）,int（4字节）
     *
     * @param arg1 类型1  注意 ：args1<0
     * @return buffer
     */
    @Override
    public IoBuffer getWriteBufferA(int arg1, Object... paras) {
        return getWriteBuffer(arg1, 0, null, paras);
    }

    /**
     * 构建数据包 ，处理二级类型数据包
     *
     * @param arg1  类型1
     * @param arg2  类型2
     * @param paras 待发送的数据
     *              paras数据-----> length+msg+length+msg ... ...
     *              length: byte(1字节),short（2字节）,int（4字节）
     * @return buffer
     */
    @Override
    public IoBuffer getWriteBufferB(int arg1, int arg2, Object... paras) {
        return getWriteBuffer(arg1,arg2,null,paras);  //To change body of implemented methods use File | Settings | File Templates.
    }

    /**
     * 是否注册该数据包（只针对数据发:client---->server）
     *
     * @return
     */
    @Override
    public boolean AutoMapper() {
        return true;  //To change body of implemented methods use File | Settings | File Templates.
    }

    /**
     * 构建数据包
     * @param arg1 类型1
     * @param arg2  类型2
     * @param buffer 申请的buf
     * @param paras 待发送的数据
     *              paras数据-----> length+msg+length+msg ... ...
     *              length: byte(1字节),short（2字节）,int（4字节）
     * @return buffer
     */
    private IoBuffer getWriteBuffer(int arg1,int arg2,IoBuffer buffer,Object...paras){
        if (buffer==null){
            buffer= IoBuffer.allocate(0x40).setAutoExpand(true);
        }
        buffer.putShort(Short.MIN_VALUE);//包长占2字节
        buffer.put((byte) arg1);
        if (arg2!=0)buffer.put((byte) arg2);
        for (Object para:paras){
            if (para instanceof Byte){
                buffer.put((Byte) para);  // 占1字节
            }else  if ((para instanceof String)){
                buffer.put(((String) para).getBytes());
            } else if (para instanceof Integer){
                buffer.putInt((Integer) para);    //占4字节
            }else  if (para instanceof Short){
                buffer.putShort((Short) para);  //占2字节
            }
        }
        buffer.putShort(0, (short)(buffer.position()-0x2));
        buffer.flip();
        return buffer;
    }



    public static void main(String[]args) throws CharacterCodingException {
        IoBuffer buffer=IoBuffer.allocate(0x40).setAutoExpand(true);
        buffer.putShort(Short.MAX_VALUE);
        buffer.put("===".getBytes());
        buffer.putShort(0, (short) (buffer.position()- 0x2));
        buffer.flip();
        int length=buffer.getShort();
        System.out.println("长度:"+length+"===内容是:"+ buffer.getString(length,decoder));

    }


}
